package com.example.fastjsontest.init;

import com.example.fastjsontest.annotation.ActiveFastJsonProfileInController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by Administrator on 2019/11/9.
 */
@Component
@Slf4j
public class InitRunner implements CommandLineRunner,ApplicationContextAware {
    private AnnotationConfigServletWebServerApplicationContext myapplicationContext;

    private ConcurrentHashMap<String,ActiveFastJsonProfileInController> hashmap = new ConcurrentHashMap<String,ActiveFastJsonProfileInController>();


    @Override
    public void run(String... args) throws Exception {
        RequestMappingHandlerMapping handlerMapping = myapplicationContext.getBean(RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods();
        for (HandlerMethod handlerMethod : handlerMethods.values()) {
            Class<?> beanType = handlerMethod.getBeanType();
            ActiveFastJsonProfileInController activeFastJsonProfileInControllerAnnotation = handlerMethod.getMethodAnnotation(ActiveFastJsonProfileInController.class);
            if (activeFastJsonProfileInControllerAnnotation == null) {
                continue;
            }
            String profile = activeFastJsonProfileInControllerAnnotation.profile();

            //获取方法级别的映射
            RequestMapping requestMapping = handlerMethod.getMethodAnnotation(RequestMapping.class);
            String[] methodLevelRequestMappingUrls = requestMapping.value();

            RequestMapping classLevelRequestMapping = beanType.getAnnotation(RequestMapping.class);
            String[] classLevelRequestMappingUrls;
            if (classLevelRequestMapping != null) {
                classLevelRequestMappingUrls = classLevelRequestMapping.value();
                for (String methodLevelRequestMappingUrl : methodLevelRequestMappingUrls) {
                    for (String classLevelRequestMappingUrl : classLevelRequestMappingUrls) {
                        String qualifiedUrl = classLevelRequestMappingUrl + methodLevelRequestMappingUrl;
                        hashmap.put(qualifiedUrl, activeFastJsonProfileInControllerAnnotation);
                    }
                }
            } else {
                for (String methodLevelRequestMappingUrl : methodLevelRequestMappingUrls) {
                    hashmap.put(methodLevelRequestMappingUrl, activeFastJsonProfileInControllerAnnotation);
                }
            }
        }

        myapplicationContext.registerBean(VoProfileRegistry.class);
        VoProfileRegistry registry = myapplicationContext.getBean(VoProfileRegistry.class);
        registry.setHashmap(hashmap);

        log.info("VoProfileRegistry:{}",hashmap);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.myapplicationContext = (AnnotationConfigServletWebServerApplicationContext) applicationContext;
    }
}
